//
// Created by LONG on 2020/10/17.
//

#ifndef O5G_SRC_CCORE_INCLUDE_O5G3GPPTYPES_H_
#define O5G_SRC_CCORE_INCLUDE_O5G3GPPTYPES_H_

#include <netinet/in.h>
#include "../../../lib/csp/include/cspApi.h"

#ifdef __cplusplus
extern "C"
{
#endif

enum
{
    O5G_RAN_DUPLEX_MODE_TDD,
    O5G_RAN_DUPLEX_MODE_FDD,
    O5G_RAN_DUPLEX_MODE_BUTT
};

enum
{
    O5G_RAN_CP_TYPE_NORMAL,
    O5G_RAN_CP_TYPE_EXTEND,
    O5G_RAN_CP_TYPE_BUTT
};

enum
{
    O5G_RAN_SCS_15KHz,
    O5G_RAN_SCS_30KHz,
    O5G_RAN_SCS_60KHz,
    O5G_RAN_SCS_120KHz,
    O5G_RAN_SCS_240KHz,
    O5G_RAN_SCS_BUTT
};

typedef struct
{
    uint32_t v:24;
}  __attribute__ ((packed)) uint24_t;

#define O5G_PLMN_ID_LEN                 3

typedef struct O5gPlmnId
{
BF_ED_AUTO(
    uint8_t mcc2:4,
    uint8_t mcc1:4)
BF_ED_AUTO(
    uint8_t mnc1:4,
    uint8_t mcc3:4)
BF_ED_AUTO(
    uint8_t mnc3:4,
    uint8_t mnc2:4)
} __attribute__ ((packed)) S_O5gPlmnId;

typedef struct O5gPlmnIdAdpt
{
    uint16_t mcc;
    uint16_t mnc;
    uint16_t mncLen;
} __attribute__ ((packed)) S_O5gPlmnIdAdpt;

uint16_t O5G_PlmnId_Mcc(S_O5gPlmnId *pPlmnId);
uint16_t O5G_PlmnId_Mnc(S_O5gPlmnId *pPlmnId);
uint16_t O5G_PlmnId_MncLen(S_O5gPlmnId *pPlmnId);
void     O5G_PlmnId_Build(S_O5gPlmnId *pPlmnId, uint16_t mcc, uint16_t mnc, uint16_t mncLen);

typedef struct O5gSfnSlot
{
    uint16_t sfn;
    uint16_t slot;
} S_O5gSfnSlot;

void O5G_SfnSlot_Add(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint16_t n);
void O5G_SfnSlot_Sub(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint16_t n);
void O5G_SfnSlot_ToU32(uint16_t sfn, uint16_t slot, uint16_t slotNum, uint32_t *sfnSlot);
void O5G_SfnSlot_FromU32(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint32_t sfnSlot);

typedef struct ogs_eps_tai_s {
    S_O5gPlmnId plmn_id;
    uint16_t tac;
} __attribute__ ((packed)) ogs_eps_tai_t;

typedef struct ogs_5gs_tai_s {
    S_O5gPlmnId plmn_id;
    uint24_t tac;
} __attribute__ ((packed)) ogs_5gs_tai_t;

typedef struct ogs_e_cgi_s {
    S_O5gPlmnId plmn_id;
    uint32_t cell_id; /* 28 bit */
} __attribute__ ((packed)) ogs_e_cgi_t;

typedef struct ogs_nr_cgi_s {
    S_O5gPlmnId plmn_id;
    uint64_t cell_id; /* 36 bit */
} __attribute__ ((packed)) ogs_nr_cgi_t;


#define O5G_IPV4_LEN                4
#define O5G_IPV6_LEN                16
#define O5G_IPV4V6_LEN              20
typedef struct O5gIp
{
    uint32_t addr4;
    uint8_t  addr6[O5G_IPV6_LEN];
    uint32_t len;
BF_ED_AUTO(
    uint8_t ipv4:1,
    uint8_t ipv6:1,
    uint8_t reserved:6)
} S_O5gIp;

typedef struct O5gIpStr
{
    char addr4[INET_ADDRSTRLEN];
    char addr6[INET6_ADDRSTRLEN];
    uint32_t len;
BF_ED_AUTO(
    uint8_t ipv4:1,
    uint8_t ipv6:1,
    uint8_t reserved:6)
} S_O5gIpStr;

#ifdef __cplusplus
}
#endif

#endif //O5G_SRC_CCORE_INCLUDE_O5G3GPPTYPES_H_
